package com.lenovo.leos.filebrowser.engine.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.StatFs;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Video;
import android.text.InputFilter;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.lenovo.leos.filebrowser.R;
import com.lenovo.leos.filebrowser.engine.model.IconifiedText;
import com.lenovo.leos.filebrowser.engine.operation.FileCompressor;
import com.lenovo.leos.filebrowser.engine.operation.FileMan;
import com.lenovo.leos.filebrowser.ui.FileDialog;

public class FileUtil {

	/** TAG for log messages. */
	private static final String TAG = "FileUtils";
	private static MimeTypes mMimeTypes = null;
	private static HashMap<String, Drawable> mMimeIconMap;
	private static MimeTypes mMimeTypesOfDefaultFolder = null;

	/*
	 * update 2010-11-3 xie
	 */
	// public final static String sdroot = "/sdcard";
	public final static String sdroot = "/mnt/sdcard";
	public static final File GPS_MAP_DIR = new File(sdroot + "/gpsmap");
	// public static final File[] SYS_FOLDERS = {new File("/sdcard/camera"), new
	// File("/sdcard/document"),
	// new File("/sdcard/music"), new File("/sdcard/video")};
	public static final File[] SYS_FOLDERS = { new File(sdroot + "/camera"),
			new File(sdroot + "/document"), new File(sdroot + "/music"),
			new File(sdroot + "/video") };
	public final static int FILE_NAME_NUM_MAX = 85;
	public static final File SYSDIR_ROOT = new File(sdroot + "/LeZone Library");
	public final static String SYSDIR[] = { "Music", "Videos", "Photos",
			"E-Books", "Documents", "Recent" };
	public final static String invalidDir = "LOST.DIR";
	public static final String MIMETYPE_CATEGORY_FOR_DIR = "dir";
	public static final String MIMETYPE_FOR_COM_DIR = MIMETYPE_CATEGORY_FOR_DIR
			+ "/com";
	public static final String MIMETYPE_FOR_SYS_DIR = MIMETYPE_CATEGORY_FOR_DIR
			+ "/sys";
	public final static int _CREATEDIR = 8;
	public final static int _DECOMPRESS = 6;

	// added by guzhaohui
	// private static DisplayMetrics mdisplayMetric=null;
	// private static PopupMenu compressFileDialog=null;
	//
	// final private static int DIALOG_SHOW_XSCALE=3;
	// final private static int DIALOG_SHOW_YSCALE=3;
	//
	// final private static int ENTRY_DIALOG_WEIGHT=400;
	// final private static int ENTRY_DIALOG_HEIGHT=250;
	//
	// final private static int ALERT_DIALOG_WEIGHT=400;
	// final private static int ALERT_DIALOG_HEIGHT=250;

	/**
	 * Whether the filename is a video file.
	 * 
	 * @param filename
	 * @return
	 */
	/*
	 * public static boolean isVideo(String filename) { String mimeType =
	 * getMimeType(filename); if (mimeType != null &&
	 * mimeType.startsWith("video/")) { return true; } else { return false; } }
	 */

	/*
	 * update 2010-11-3 xie
	 */
	public static boolean isSysFile(final File file) {
		if (null == file || !file.exists()) {
			Log.e(TAG, "file is invalid in isSysFile");
			return false;
		} else {
			// if(file.getAbsolutePath().startsWith(SYSDIR_ROOT.getAbsolutePath()))
			boolean res = false;
			for (File f : SYS_FOLDERS) {
				if (f.getAbsolutePath().equals(file.getAbsolutePath())) {
					res = true;
					break;
				}
			}
			return res;
		}
	}

	/*
	 * update 2010-11-3 xie
	 */
	public static boolean isSysOrReservedDir(final File file) {
		if (null == file || !file.isDirectory()) {
			Log.e(TAG, "file is null or not a dir in isSysOrReservedDir");
			return false;
		} else {
			if (!isSysFile(file))
				return false;
			else {
				if (file.equals(SYSDIR_ROOT))
					return true;
				else {
					if (!file.getParentFile().equals(SYSDIR_ROOT))
						return false;
					else {
						for (String str : SYSDIR) {
							if (file.getName().equals(str))
								return true;
						}

						return false;
					}
				}
			}
		}
	}

	/**
	 * Whether the URI is a local one.
	 * 
	 * @param uri
	 * @return
	 */
	public static boolean isLocal(String uri) {
		if (uri != null && !uri.startsWith("http://")) {
			return true;
		}
		return false;
	}

	/**
	 * Gets the extension of a file name, like ".png" or ".jpg".
	 * 
	 * @param uri
	 * @return Extension including the dot("."); "" if there is no extension;
	 *         null if uri was null.
	 */
	public static String getExtension(String uri) {
		if (uri == null) {
			return null;
		}

		int dot = uri.lastIndexOf(".");
		if (dot >= 0) {
			return uri.substring(dot);
		} else {
			// No extension.
			return "";
		}
	}

	// add by PH 091118
	/**
	 * Gets the file name without the Extension of a file name.
	 * 
	 * @param filename
	 * @return The file name without the Extension including the dot(".");
	 *         Filename if there is no extension; null if filename was null.
	 */
	public static String getFileNameWithoutExt(String filename) {
		if (filename == null) {
			return null;
		}

		int dot = filename.lastIndexOf(".");
		if (dot >= 0) {
			return filename.substring(0, dot);
		} else {
			// No extension.
			return filename;
		}
	}

	// end PH 091118

	/**
	 * Returns true if uri is a media uri.
	 * 
	 * @param uri
	 * @return
	 */
	public static boolean isMediaUri(String uri) {
		if (uri.startsWith(Audio.Media.INTERNAL_CONTENT_URI.toString())
				|| uri.startsWith(Audio.Media.EXTERNAL_CONTENT_URI.toString())
				|| uri.startsWith(Video.Media.INTERNAL_CONTENT_URI.toString())
				|| uri.startsWith(Video.Media.EXTERNAL_CONTENT_URI.toString())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Convert File into Uri.
	 * 
	 * @param file
	 * @return uri
	 */
	public static Uri getUri(File file) {
		// String filename = file.getName();
		// String filepath = file.getAbsolutePath();
		// Log.d(TAG, "***********filepath========" + filepath);
		// String pathwithoutname = filepath.substring(0, filepath.length() -
		// filename.length());
		// Log.d(TAG, "***********pathwithoutname========" + pathwithoutname +
		// Uri.encode(file.getName()));
		// Log.d(TAG, "***********URI========" + Uri.parse("file://" +
		// pathwithoutname + Uri.encode(file.getName())).toString());
		// return Uri.parse("file://" + pathwithoutname +
		// Uri.encode(file.getName()));
		return Uri.parse("file://" + file.getAbsolutePath());
	}

	/**
	 * Convert File into String.
	 * add 2012-12-16 by xieqm
	 * 
	 * @param file
	 * @return file content
	 */
	public static String getFile(File file) {
		StringBuffer content = new StringBuffer();
		try {
			FileReader fileReader = new FileReader(file);
			BufferedReader bufferReader = new BufferedReader(fileReader);
			String str = null;
			while ((str = bufferReader.readLine()) != null) {
				content.append(str).append("\n");
			}
			bufferReader.close();
			fileReader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		Log.d(TAG, "content.toString()=====" + content.toString());
		return content.toString();
	}

	/**
	 * Convert Uri into File.
	 * 
	 * @param uri
	 * @return file
	 */
	public static File getFile(Uri uri) {
		if (uri != null) {
			String filepath = uri.toString();
			if (filepath.startsWith("file://")) {
				filepath = filepath.substring(7);
			}
			return new File(filepath);
		}
		return null;
	}

	/**
	 * Returns the path only (without file name).
	 * 
	 * @param file
	 * @return
	 */
	public static File getPathWithoutFilename(File file) {
		if (file != null) {
			if (file.isDirectory()) {
				// no file to be split off. Return everything
				return file;
			} else {
				String filename = file.getName();
				String filepath = file.getAbsolutePath();

				// Construct path without file name.
				String pathwithoutname = filepath.substring(0,
						filepath.length() - filename.length());
				if (pathwithoutname.endsWith("/")) {
					pathwithoutname = pathwithoutname.substring(0,
							pathwithoutname.length() - 1);
				}
				return new File(pathwithoutname);
			}
		}
		return null;
	}

	/**
	 * Constructs a file from a path and file name.
	 * 
	 * @param curdir
	 * @param file
	 * @return
	 */
	public static File getFile(String curdir, String file) {
		String separator = "/";
		if (curdir.endsWith("/")) {
			separator = "";
		}
		File clickedFile = new File(curdir + separator + file);
		return clickedFile;
	}

	public static File getFile(File curdir, String file) {
		return getFile(curdir.getAbsolutePath(), file);
	}

	public static boolean isInvalidDir(File dir) {
		return dir.getName().toUpperCase().equals(FileUtil.invalidDir);
	}

	// [improve]
	public static String getFileSizeString(long lSize) {
		String size;
		int iPoint;

		if (lSize < 1024) {
			size = lSize + "B";
		} else if (lSize < 1024 * 1024) {
			size = String.valueOf(lSize / 1024.0);
			iPoint = size.indexOf(".");
			size = size.substring(0, size.length() > iPoint + 3 ? iPoint + 3
					: size.length())
					+ "KB";
		} else if (lSize < 1024 * 1024 * 1024) {
			size = String.valueOf(lSize / 1024.0 / 1024);
			iPoint = size.indexOf(".");
			size = size.substring(0, size.length() > iPoint + 3 ? iPoint + 3
					: size.length())
					+ "MB";
		} else if (lSize < 1024L * 1024L * 1024L * 1024L) {
			// Log.d(TAG, "###lSize_G="+lSize);
			size = String.valueOf(lSize / 1024.0 / 1024 / 1024);
			iPoint = size.indexOf(".");
			size = size.substring(0, size.length() > iPoint + 3 ? iPoint + 3
					: size.length())
					+ "GB";
		} else if (lSize < 1024L * 1024L * 1024L * 1024L * 1024L) {
			// Log.d(TAG, "###lSize_T="+lSize);
			size = String.valueOf(lSize / 1024.0 / 1024 / 1024 / 1024);
			iPoint = size.indexOf(".");
			size = size.substring(0, size.length() > iPoint + 3 ? iPoint + 3
					: size.length())
					+ "TB";
		} else {
			// Log.d(TAG, "###lSize_Unknown="+lSize);
			size = "unknown";
		}

		return size;
	}

	public static String getFileSizeString(File file) {
		if (null == file || !file.exists())
			return null;

		return getFileSizeString(file.length());
	}

	public static String getFileModifiedTimeString(Context context, long time) {

		Date modifTime = new Date(time);
		String modiftime = DateFormat.getTimeFormat(context).format(modifTime);
		String modifdate = DateFormat.getDateFormat(context).format(modifTime);
		return modifdate + " " + modiftime;
	}

	public static String getFileModifiedTimeString(Context context, File file) {
		if (null == file || !file.exists())
			return null;

		return getFileModifiedTimeString(context, file.lastModified());
	}

	private static void initDefaultFolderOfMimeTypes(Context context) {
		Log.i(TAG, "==> initMimeTypes");
		if (mMimeTypesOfDefaultFolder == null) {
			MimeTypeParser mtp = new MimeTypeParser();

			// XmlResourceParser in =
			// getResources().getXml(com.android.internal.R.xml.mimetypes);
			XmlResourceParser in = context.getResources().getXml(
					R.xml.defaultfolder);
			try {
				mMimeTypesOfDefaultFolder = mtp.fromXmlResource(in);
			} catch (XmlPullParserException e) {
				Log.e(TAG, "==>XmlPullParserException", e);
				throw new RuntimeException("==>XmlPullParserException");
			} catch (IOException e) {
				Log.e(TAG, "==>IOException", e);
				throw new RuntimeException("==>IOException", e);
			}

		}
	}

	public static String getDefaultFolderOfMimeType(Context context,
			String mimetype) {
		if (mMimeTypesOfDefaultFolder == null)
			initDefaultFolderOfMimeTypes(context);

		if (null == mimetype) {
			Log.e(TAG, "mimetype is null");
			return null;
		} else {
			return mMimeTypesOfDefaultFolder
					.getDefaultFolderOfMimeType(mimetype);
		}
	}

	private static void initMimeTypes(Context context) {
		Log.i(TAG, "==> initMimeTypes");

		if (mMimeTypes == null) {
			MimeTypeParser mtp = new MimeTypeParser();

//			XmlResourceParser in = context.getResources().getXml(
//					com.android.internal.R.xml.mimetypes);
			 XmlResourceParser in =
			 context.getResources().getXml(R.xml.mimetypes);

			Log.i(TAG, "before fromXmlResource");
			try {
				mMimeTypes = mtp.fromXmlResource(in);
			} catch (XmlPullParserException e) {
				Log.e(TAG, "==>XmlPullParserException", e);
				throw new RuntimeException("==>XmlPullParserException");
			} catch (IOException e) {
				Log.e(TAG, "==>IOException", e);
				throw new RuntimeException("==>IOException", e);
			}
		}
	}

	public static String getMimeTypeOfFile(Context context, File file) {
		if (null == file) {
			Log.e(TAG, "file is invalid in getMimeTypeOfFile");
			return null;
		}

		Log.i(TAG, "the file path is " + file.getAbsolutePath());

		// if (mMimeTypes == null)
		// initMimeTypes(context);

		// just regard dir as common file, return a mimetype for it
		if (file.isFile()) {
			// String mine =
			// mMimeTypes.getMimeType(file.getName().toLowerCase());

			// get extension here
			// maybe udpate getExtension()
			String name = file.getName().toLowerCase();
			String extension = null;
			int dot = name.lastIndexOf(".");
			if (dot >= 0) {
				extension = name.substring(dot + 1);
			}

			// get mimetype with the MimeTypeMap class in android
			String sys = null;
			if (extension != null) {
				sys = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
						extension);
			}
			if (null != sys) {
				Log.i(TAG, "the sys is " + sys);
			}
			// return mMimeTypes.getMimeType(file.getName().toLowerCase());
			return sys;

		} else if (file.isDirectory()) {
			if (FileUtil.isSysOrReservedDir(file))
				return FileUtil.MIMETYPE_FOR_SYS_DIR;
			else
				return FileUtil.MIMETYPE_FOR_COM_DIR;
		} else {
			Log.e(TAG, "file is neither a file nor a folder");
			return null;
		}
	}

	public static String getMimeTypeOfFile(Context context, String name) {

		if (null == name || 0 == name.length())
			return null;

		String extension = null;
		int dot = name.lastIndexOf(".");
		if (dot >= 0) {
			extension = name.substring(dot + 1);
		}

		// get mimetype with the MimeTypeMap class in android
		String sys = null;
		if (extension != null)
			sys = MimeTypeMap.getSingleton()
					.getMimeTypeFromExtension(extension);

		if (null != sys)
			Log.i(TAG, "the sys is " + sys);

		// return mMimeTypes.getMimeType(file.getName().toLowerCase());
		return sys;
	}

	private static Drawable getIconForDir(Context context, File file) {
		if (null == file || !file.exists() || !file.isDirectory())
			return null;
		else {
			if (FileUtil.isSysOrReservedDir(file)) {
				String name = file.getName();

				// context.getResources().getIdentifier(name, defType,
				// defPackage);

				// icon = context.getResources().getDrawable(
				// R.drawable.defaultfolder);
			} else {
			}
			// icon = context.getResources().getDrawable(
			// R.drawable.icon_default_folder);
		}
		return null;
	}

	private static Drawable getIconForMimetype(Context context, String mimetype) {
		// Log.i(TAG, "==> getDrawableForMimetype");
		// Log.i(TAG, "the mimetype is " + mimetype);

		if (null == mimetype || 0 == mimetype.length()) {
			Log.e(TAG, "mimetype is null or empty in getIconForMimetype");
			return null;
		}

		Drawable icon = null;
		if (null == mMimeIconMap)
			mMimeIconMap = new HashMap<String, Drawable>();

		icon = mMimeIconMap.get(mimetype);

		if (null == icon) {

			if (mimetype.startsWith(FileUtil.MIMETYPE_CATEGORY_FOR_DIR)) {
				if (mimetype.equals(FileUtil.MIMETYPE_FOR_COM_DIR)) {
					// Log.i(TAG, "it is a common folder");
					icon = context.getResources().getDrawable(
							R.drawable.icon_default_folder);
				} else if (mimetype.equals(FileUtil.MIMETYPE_FOR_SYS_DIR)) {
					// Log.i(TAG, "it is a sys folder");
					// String type =
					// mimetype.substring(FileUtil.MIMETYPE_CATEGORY_FOR_DIR.length()
					// + 1);
					// int resID = context.getResources().getIdentifier(
					// "icon_folder_"+type, "drawable",
					// "com.lenovo.gemini.filebrowser");
					//
					// if (0 == resID)
					// icon =
					// context.getResources().getDrawable(R.drawable.icon_default_folder);
					// else
					// icon = context.getResources().getDrawable(resID);

					icon = context.getResources().getDrawable(
							R.drawable.icon_folder_sys);
				} else {
					Log.e(TAG, "invalid mimetype for folder");
				}
			} else {
				PackageManager pm = context.getPackageManager();
				Intent intent = new Intent(Intent.ACTION_VIEW);
				intent.setDataAndType(Uri.fromParts("file", "", null), mimetype);

				List<ResolveInfo> lri = pm.queryIntentActivities(intent,
						PackageManager.MATCH_DEFAULT_ONLY);
				List<ResolveInfo> lriRe = pm.queryBroadcastReceivers(intent,
						PackageManager.MATCH_DEFAULT_ONLY);
				if (lri != null && lri.size() > 0) {
					icon = lri.get(0).loadIcon(pm);
				} else if (lriRe != null && lriRe.size() > 0) {
					icon = lriRe.get(0).loadIcon(pm);
				}
			}

			if (null == icon)
				icon = context.getResources().getDrawable(
						R.drawable.icon_unknown_file);
			mMimeIconMap.put(mimetype, icon);
		}

		return icon;
	}

	public static Drawable getDefaultIconForFile(Context context, File file) {
		if (null == file || !file.exists()) {
			Log.e(TAG, "file is null or nonexistent in getDefaultIconForFile");
			return null;
		} else {
			Drawable icon = null;
			String mimetype = getMimeTypeOfFile(context, file);
			if (null == mimetype) {
				if (FileUtil.getExtension(file.getName()).equals(".p12"))
					icon = context.getResources().getDrawable(
							R.drawable.ic_menu_login);
				else
					icon = context.getResources().getDrawable(
							R.drawable.icon_unknown_file);
			} else
				icon = getIconForMimetype(context, mimetype);

			return icon;
		}
	}

	// //added by guzhaohui
	// private static void getDisplayMetrics(Context context){
	// mdisplayMetric=new DisplayMetrics();
	// ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(mdisplayMetric);
	// // Log.d(TAG,"height"+mdisplayMetric.heightPixels/2);
	// // Log.d(TAG, "wight"+mdisplayMetric.widthPixels/2);
	// }

	public static void openFile(final Activity context, final File aFile) {
		Log.d(TAG, "==>openFile");

		if (null == aFile || !aFile.exists()) {
			Toast.makeText(
					context,
					aFile
							+ context
									.getString(R.string.error_file_does_not_exists),
					Toast.LENGTH_SHORT).show();
			return;
		}

		Intent intent = new Intent();
		final String fileName = aFile.getName().toLowerCase();
		Uri data = FileUtil.getUri(aFile);
		Log.d(TAG, "==> FileUri = " + data.toString());

		if (fileName.endsWith(".ics")) {
			intent.setAction("com.android.calendar.import");
			intent.putExtra("Operation", "add");
			intent.putExtra("Path", Uri.fromFile(aFile).toString());
			context.sendBroadcast(intent);
			// add by PH 091022
			/*
			 * if (context instanceof FileBrowser) { FileBrowser my =
			 * (FileBrowser) context; my.browseDir(new File("/sdcard")); }
			 */
			// end PH 091022
		} else if (fileName.endsWith(".p12")) {
			try {
				FileInputStream stream = new FileInputStream(aFile);
				ByteArrayOutputStream cert = new ByteArrayOutputStream(1000);
				byte[] b = new byte[1000];
				int n;
				while ((n = stream.read(b)) != -1)
					cert.write(b, 0, n);
				stream.close();
				cert.close();
				Log.d("Certtool",
						"certificate install.............................................................................");
				// if(CertTool.getInstance().isPkcs12Key(cert.toByteArray())){
				// CertTool.getInstance().addCertificate(cert.toByteArray(),
				// context);
				// }else
				{
					Toast.makeText(
							context,
							aFile
									+ context
											.getString(R.string.application_not_available),
							Toast.LENGTH_SHORT).show();
					Log.d("error file",
							"zhang...........................................");
				}
			} catch (IOException e) {
				Log.i(TAG, "==>  catch a IOException in addCertificate");
			}
		} else if (FileUtil.isCompressFile(aFile)) {
			DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
				// @Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					decompressFile(context, aFile);
				}
			};

			FileDialog.DialogButton dbp = new FileDialog.DialogButton(
					R.string.alert_dialog_ok, listener);
			FileDialog.DialogButton dbn = new FileDialog.DialogButton(
					R.string.alert_dialog_cancel, null);

			FileDialog.showMsgWithTwoButton(context, R.string.dlg_open_title,
					R.string.dlg_open_msg_decomp, dbp, dbn);
		} else {
			String type = getMimeTypeOfFile(context, aFile);

			Log.i(TAG, "the mimetype is " + type);

			intent.setAction(Intent.ACTION_VIEW);
			intent.setDataAndType(data, type);
			try {
				context.startActivity(intent);
			} catch (ActivityNotFoundException e) {
				Log.i(TAG, "can not open this file");

				FileDialog.DialogButton dbn = new FileDialog.DialogButton(
						R.string.alert_dialog_ok, null);
				FileDialog.showMsgWithOneButton(context,
						R.string.dlg_open_title, R.string.dlg_open_msg_unknown,
						dbn);
			}
		}
	}

	private static boolean checkEndsWithInStringArray(String checkItsEnd,
			String[] fileEndings) {
		// Log.d(TAG, "==> checkEndsWithInStringArray");
		for (String aEnd : fileEndings) {
			if (checkItsEnd.toLowerCase().endsWith(aEnd))
				return true;
		}
		return false;
	}

	public static boolean needThumbnailOrNot(Context context, File file) {
		if (null == file || !file.exists())
			return false;
		else {
			String mimetype = getMimeTypeOfFile(context, file);

			if (null == mimetype)
				return false;
			else {
				if (mimetype.startsWith("image")
						|| mimetype.startsWith("video")
						|| mimetype.startsWith("dir"))
					return true;
				else
					return false;
			}
		}
	}

	public static boolean isImageFile(Context context, File file) {
		if (null == file || !file.isFile())
			return false;
		else {
			String mimetype = getMimeTypeOfFile(context, file);

			if (null == mimetype)
				return false;
			else {
				if (mimetype.startsWith("image"))
					return true;
				else
					return false;
			}
		}
	}

	public static boolean isVideoFile(Context context, File file) {
		if (null == file || !file.isFile())
			return false;
		else {
			String mimetype = getMimeTypeOfFile(context, file);

			if (null == mimetype)
				return false;
			else {
				if (mimetype.startsWith("video"))
					return true;
				else
					return false;
			}
		}
	}

	public static String getFileTypeString(Context context, File file) {
		if (null == file || !file.exists())
			return null;

		if (file.isDirectory()) {
			if (FileUtil.isSysOrReservedDir(file))
				return context.getResources().getString(
						R.string.filetype_sysfolder);
			else
				return context.getResources().getString(
						R.string.filetype_folder);
		} else if (file.isFile()) {
			String name = file.getName();

			int strId = R.string.unknownfile;
			if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingImage))) {
				strId = R.string.picturefile;
			} else if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingWebText))) {
				strId = R.string.htmlfile;
			} else if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingPackage))) {
				strId = R.string.compressfile;
			} else if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingAudio))) {
				strId = R.string.audiofile;
			} else if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingVideo))) {
				strId = R.string.videofile;
			} else if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingOffice))) {
				strId = R.string.Document;
			} else if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingAndroid))) {
				strId = R.string.android_file;
			} else if (FileUtil.getExtension(name).equals(".txt")) {
				strId = R.string.txt_file;
			} else if (checkEndsWithInStringArray(name, context.getResources()
					.getStringArray(R.array.fileEndingEbook))) {
				strId = R.string.fi_type_ebook;
			} else if (FileUtil.getExtension(name).equals(".vcf")) {
				strId = R.string.vcf_file;
			} else if (FileUtil.getExtension(name).equals(".csv")) {
				strId = R.string.csv_file;
			} 

			return context.getResources().getString(strId);
		} else
			return null;

	}

	// [improve]
	public static boolean isNameUseable(String name, boolean isDirectory) {
		// Log.d(TAG, "==> isNameUseable");

		// /\:?<>"|*.'
		// && name.startsWith(" ") == false
		// && ((isDerectory==true)?(name.contains(".") == false):true)
		boolean ret = false;
		if (name.length() > 0) {
			if (name.startsWith(".") == false && name.contains("/") == false
					&& name.contains("\\") == false
					&& name.contains(":") == false
					&& name.contains("?") == false
					&& name.contains("\uff1f") == false
					&& name.contains("<") == false
					&& name.contains(">") == false
					&& name.contains("\"") == false
					&& name.contains("\t") == false
					&& name.contains("|") == false
					&& name.contains("*") == false
					&& name.contains("\n") == false
					&& name.contains("\r") == false
					&& name.contains("'") == false) {
				ret = true;
			}
		}

		return ret;
	}

	public static String getValidFolderName(final File parent, String name) {
		String dir = parent.getAbsolutePath();

		File file = new File(dir + "/" + name);

		int i = 0;
		while (file.exists()) {
			i++;
			file = new File(dir + "/" + name + "(" + String.valueOf(i) + ")");
		}

		return file.getName();

	}

	public static void newFolder(final Activity activity, final File parent,
			final Handler handler) {

		if (null == activity || null == parent || !parent.isDirectory())
			return;

		LayoutInflater factory = LayoutInflater.from(activity);

		final View textEntryView = factory.inflate(
				R.layout.dlg_content_newname, null);
		final TextView textView = (TextView) textEntryView
				.findViewById(R.id.filename_view);
		textView.setText(R.string.dlg_newfolder_msg_input);

		final EditText eText = (EditText) textEntryView
				.findViewById(R.id.filename_edit);
		String name = getValidFolderName(parent, activity.getResources()
				.getString(R.string.default_dir_name));
		eText.setText(name);
		eText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(
				FileUtil.FILE_NAME_NUM_MAX) });
		eText.selectAll();

		final Runnable reOpen = new Runnable() {
			// @Override
			public void run() {
				Log.i(TAG, "==> run");
				// TODO Auto-generated method stub
				FileUtil.newFolder(activity, parent, handler);
			}
		};

		new AlertDialog.Builder(activity)
				.setTitle(R.string.dlg_newfolder_title)
				.setView(textEntryView)
				.setPositiveButton(R.string.alert_dialog_ok,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int whichButton) {
								String name = eText.getText().toString().trim();
								Log.i(TAG, " new folder name = " + name);
								Log.i(TAG,
										"the name length is "
												+ String.valueOf(name.length()));
								Log.i(TAG, "user input is"
										+ eText.getText().toString());
								if (name.length() > 0
										&& name.length() <= FileUtil.FILE_NAME_NUM_MAX) {
									if (FileUtil.isNameUseable(name, true) == false) {
										Toast.makeText(activity,
												R.string.namebad,
												Toast.LENGTH_SHORT).show();
										handler.post(reOpen);
									} else {
										Log.i(TAG, "the name is" + name);
										File f = new File(parent.getPath()
												+ "/" + name);
										Log.i(TAG, "the name is" + f.getName());
										Log.i(TAG,
												"the path is"
														+ f.getAbsolutePath());
										if (f.exists()) {
											Log.i(TAG, "the file is existed");
										}
										if (f.exists() && f.isDirectory()) {
											Toast.makeText(activity,
													R.string.nameexist,
													Toast.LENGTH_SHORT).show();
											handler.post(reOpen);
										} else if (FileUtil
												.isSysOrReservedDir(f)) {
											Toast.makeText(
													activity,
													f.getName()
															+ activity
																	.getResources()
																	.getString(
																			R.string.sysReservedDir),
													Toast.LENGTH_SHORT).show();
											handler.post(reOpen);
										} else {
											Log.i(TAG,
													"before create new folder");
											// create the new folder
											StatFs sf;
											sf = new StatFs(FileUtil.sdroot);
											if (((long) sf.getAvailableBlocks() * sf
													.getBlockSize()) < (long) 10 * 1024) {
												// no enough space
												new AlertDialog.Builder(
														activity)
														.setTitle(
																R.string.remind)
														.setMessage(
																R.string.nospaceonsd)
														.setPositiveButton(
																R.string.alert_dialog_ok,
																new DialogInterface.OnClickListener() {
																	public void onClick(
																			DialogInterface dialog,
																			int whichButton) {
																	}
																}).show();
											} else {
												Bundle bundle = new Bundle();
												bundle.putInt("request_code",
														FileUtil._CREATEDIR);
												bundle.putString(
														"parent path",
														parent.getAbsolutePath());
												bundle.putString("file name",
														name);

												Intent intent = new Intent();
												intent.setClass(activity,
														FileMan.class);
												intent.putExtras(bundle);
												((Activity) activity)
														.startActivityForResult(
																intent,
																FileUtil._CREATEDIR);

											}
										}
									}
								} else if (name.length() > FileUtil.FILE_NAME_NUM_MAX) {
									Toast.makeText(activity,
											R.string.name_too_long,
											Toast.LENGTH_SHORT).show();
									handler.post(reOpen);
								} else {
									Toast.makeText(activity,
											R.string.nameempty,
											Toast.LENGTH_SHORT).show();
									handler.post(reOpen);
								}
							}
						})
				.setNegativeButton(R.string.alert_dialog_cancel,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int whichButton) {
								// User clicked cancel
								// so do some stuff
							}
						}).show();
	}

	public static void getThumbnailForFiles(Context context,
			List<IconifiedText> itemlist, Handler handler) {

		if (!ThumbnailService.isReady()) {
			ThumbnailService.initialize(context);
		}

		ThumbnailService.setHandler(handler);
		ThumbnailService.getThumbNailForFiles(itemlist);
	}

	public static void getThumbnailForFile(Context context, IconifiedText it,
			Handler handler) {

		if (!ThumbnailService.isReady()) {
			ThumbnailService.initialize(context);
		}

		ThumbnailService.setHandler(handler);
		ThumbnailService.getThumbNailForFile(it);
	}

	public static void decompressFile(Context context, File file) {
		Log.i(TAG, "==> decompressFile");
		if (null == file || !file.exists()

		|| !FileUtil.isCompressFile(file))
			return;

		String zipfile = file.getAbsolutePath();

		Bundle bundle = new Bundle();
		bundle.putInt("request_code", FileUtil._DECOMPRESS);

		bundle.putString("toDir", file.getParentFile().getPath());
		bundle.putString("filename", file.getName());

		if (file.getName().toLowerCase().endsWith(".zip")) {
			bundle.putBoolean("ZIP", true);
			zipfile = file.getAbsolutePath();
			bundle.putString("zipfile", zipfile);
		} else {
			bundle.putBoolean("ZIP", false);
		}

		Intent intent = new Intent();
		intent.setClass(context, FileCompressor.class);
		intent.putExtras(bundle);
		((Activity) context).startActivityForResult(intent,
				FileUtil._DECOMPRESS);
	}

	// [improve] maybe add it to FileCompress
	public static boolean isCompressFile(File file) {
		if (null == file || !file.exists()) {
			Log.e(TAG, "the file is invalid in isCompressFile");
			return false;
		} else {
			String name = file.getName();
			if (name.endsWith(".zip") || name.endsWith(".gz"))
				return true;
			else
				return false;
		}

	}

	public static void notifyMediaScanner(Context context, File file) {
		if (null == context)
			return;
		if (null != file) {
			Log.d(TAG, "sent intent to scan a file: " + file.getAbsolutePath());
			context.sendBroadcast(new Intent(
					Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
		} else {
			// [improve] use storage manager
			String state = Environment.getExternalStorageState();
			if (state.equals(Environment.MEDIA_MOUNTED)
					|| state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
				File ext = Environment.getExternalStorageDirectory();
				Log.i(TAG, "sent intent to scan sdcard");
				context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
						Uri.fromFile(ext)));
			}
		}
	}

}
